package no.fongen.os;

 public class FIFO {
    private int front, back, capacity, counter;
    private Condition dataElements, freeSpace;
    private Object[] storage;
    public FIFO(int cap) {
       storage = new Object[cap];
       capacity = cap;
       counter = cap; // Count white space
       dataElements = new Condition(0);
       freeSpace = new Condition(cap);
       front = 0; back = 0;
    }
 
    private synchronized void in(Object obj) {
       // Put data into ring buffer
       storage[back] = obj;
       back = (back+1) % capacity;
    }
 
    private synchronized Object out() {
       // Get data from ring buffer
       Object obj;
       obj = storage[front];
       front = (front+1) % capacity;
       return obj;
    }
    
 
    public void nonblockput(Object obj) {
        if (counter==0) {
            System.out.println("----------------------Queue capacity is exceeded, call ignored");
            return;
        }
       freeSpace.condWait();
       counter--;
       in(obj);
       dataElements.condNotify();
    }
 
    public void put(Object obj) {
       freeSpace.condWait();
       counter--;
       in(obj);
       dataElements.condNotify();
    }

    public Object get() {
       dataElements.condWait();
       counter++;
       Object obj = out();
       freeSpace.condNotify();
       return obj;
    }
 } 
